package org.foreningsgatan.modular.lightsources;

import java.util.List;

/**
 * Copyright (c) 2008 Joakim Back
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * @author Joakim Back
 * 
 */
public class LightSources<T extends LightSource> {
	private SourceHandler sourceHandler;

	private SourceTables sourceTables;

	private StaticLightRendererUtil<T> staticLightsRendererUtil;

	private Renderer<T> renderer;

	public LightSources() {
		sourceHandler = new SourceHandlerImpl();
		sourceTables = new SourceTables();
		renderer = new Renderer<T>(sourceHandler, sourceTables);
		staticLightsRendererUtil = new StaticLightRendererUtil<T>(
				sourceHandler, renderer);
	}

	/**
	 * Register new light source. If source has static properties, prepare a
	 * look-up table for efficient rendering.
	 * 
	 * @param source
	 */
	public void register(LightSource source) {
		sourceHandler.add(source);

		// Generate look-up table

		switch (source.getType()) {
		case STATIC:
		case DYNAMIC_POSITION:
			sourceTables.prepare(source);
			break;

		case DYNAMIC_FULL:
			// Light is fully dynamic, do not generate lookup table
			break;
		}
	}

	/**
	 * Set ambient light RGB
	 * 
	 * @param ambientLight
	 */
	public void setAmbientLight(RGB ambientLight) {
		renderer.setAmbientLight(ambientLight);
	}

	/**
	 * Render all fully static lights to a look-up map
	 * 
	 * @param size
	 */
	public void updateStaticLights(int size) {
		LightMap staticLights = staticLightsRendererUtil.render(size);

		renderer.setStaticLights(staticLights);
	}

	/**
	 * Render all lights
	 * 
	 * @param size
	 * @param offsetX
	 * @param offsetY
	 * @return
	 */
	public LightMap render(int size, int offsetX, int offsetY)
			throws Exception {
		return renderer.render(size, offsetX, offsetY, false);
	}

	public LightMap render(int size, int offsetX, int offsetY, boolean includeOffset)
			throws Exception {
		return renderer.render(size, offsetX, offsetY, includeOffset);
	}

	/**
	 * Get light sources within area
	 * 
	 * @param size
	 * @param offsetX
	 * @param offsetY
	 * @return
	 */
	public List<T> getLightSources(int size, double offsetX, double offsetY) {
		return renderer.getLightSources(size, offsetX, offsetY);
	}
}
